package org.dfl.plugin.editor.model;

import java.util.ArrayList;
import java.util.Collection;

import org.dfl.core.model.Place;
import org.dfl.core.model.XMLLoaderException;
import org.dfl.core.model.listeners.PlaceListener;
import org.dfl.messages.Messages;
import org.dfl.plugin.editor.figures.FiguresConstants;
import org.dfl.plugin.editor.markers.ModelMarkersContainer;
import org.dfl.plugin.editor.markers.ModelProblem;
import org.eclipse.swt.graphics.Font;
import org.jdom.Element;
/**
 * editor's model element that represents a place
 * @author Piotr Wlodarczyk
 *
 */
@SuppressWarnings("serial")
public class PlaceModelElement extends Shape implements PlaceListener{
	protected Place place;
	private boolean notEmptyData;
	
	public String getId(){
		return place.getId();
	}
	
	public PlaceModelElement(){
		place = getDefaultPlace();
		place.addListener(this);
	}
	
	public PlaceModelElement(Element elem) throws XMLLoaderException {
		load(elem);
	}
	
	@Override
	public String getLabelText() {
		return getPlace().getTypeContainer().getType().toString();
	}
	
	public String getTipText() {
		return Messages.PlaceModelElement_tipId+getPlace().getId()+"\n\n"+getLabelText(); //$NON-NLS-2$
	}
	
	@Override
	protected Font getLabelFont(){
		return FiguresConstants.placeFont;
	}

	@Override
	public int getMaxLabelHeight() {
		return FiguresConstants.placeMaxHeight;
	}

	@Override
	public int getMaxLabelWidth() {
		return FiguresConstants.placeMaxWidth;
	}
	
	@Override
	public void load(Element elem) throws XMLLoaderException {
		place = getDefaultPlace();
		place.load(elem);
		place.addListener(this);
		super.load(elem.getChild("graphics")); //$NON-NLS-1$
	}
	
	protected Place getDefaultPlace() {
		return new Place();
	}

	@Override
	public Element save() {
		Element root = place.save();
		Element graphicsElem =  super.save();
		root.addContent(graphicsElem);
		return root;
	}

	public Place getPlace() {
		return place;
	}
	
	@Override
	protected void addSourceConnection(ConnectionModelElement conn) throws Exception{
		firePropertyChange(Shape.SELF_PROP,null,"type"); //$NON-NLS-1$
		super.addSourceConnection(conn);
	}
	
	@Override
	protected void addTargetConnection(ConnectionModelElement conn) throws Exception{
		firePropertyChange(Shape.SELF_PROP,null,"type"); //$NON-NLS-1$
		super.addTargetConnection(conn);
	}

	// ------------------------ place listener ----------------------//
	public void tokenAdded(Place place) {
		notEmptyData = true;
		firePropertyChange(SELF_PROP, null, notEmptyData);
	}
	

	public void tokenRemoved(Place place, int histories) {
		if(histories==0){
			notEmptyData = false;
			firePropertyChange(SELF_PROP, null, notEmptyData);
		}
	}

	public boolean isNotEmptyData() {
		return notEmptyData;
	}
	
	@Override
	public Collection<ModelProblem> getProblems() {
		Collection<ModelProblem> problems = new ArrayList<ModelProblem>();
		// check inputs
		if(getPlace().getInputEdges().isEmpty()){
			problems.add(ModelMarkersContainer.createWarning(Messages.PlaceModelElement_problemNoInputs ,Messages.PlaceModelElement_name, getPlace().getId()));
		}
		if(getPlace().getOutputEdges().isEmpty()){
			problems.add(ModelMarkersContainer.createWarning(Messages.PlaceModelElement_problemNoOutpus ,Messages.PlaceModelElement_name, getPlace().getId()));
		}
			
		return problems;
	}
	
	public boolean isConnected(){
		return (!getPlace().getInputEdges().isEmpty() && !getPlace().getOutputEdges().isEmpty());
	}

}
